package vg.services.graph_view_manager;

import vg.services.data_base_manager.data.graph.Graph;
import vg.services.graph_view_manager.interfaces.IGraphViewManager;
import vg.services.graph_view_manager.interfaces.graph_comparison.AGraphComparison;
import vg.services.graph_view_manager.interfaces.graph_view.AGraphView;
import vg.services.main_manager.MainManager;

public class GraphViewManager implements IGraphViewManager {
	// Mutex
	private final Object generalMutex = new Object();
	
	// Main components
	private Class<?> graphViewClazz;
	private Class<?> graphComparisonViewClazz;
	
	public GraphViewManager() {
		try {
			graphViewClazz = Class.forName("vg.services.graph_view_manager.realization.graph_view.smart_graph_view.SmartGraphView");
			graphComparisonViewClazz = Class.forName("vg.services.graph_view_manager.realization.graph_comparison.GraphComparation");
		} catch (Exception ex) {
			MainManager.log.printException(ex);
		}
	}
	
//=============================================================================
//-----------------Setters-----------------------------------------------------	
	@Override
	public boolean setGraphComparisonViewClass(Class<AGraphComparison> clazz) {
		synchronized (generalMutex) {
			if (clazz != null) {
				graphComparisonViewClazz = clazz;
				return true;
			}
		}
		return false;
	}
	
	@Override
	public boolean setGraphViewClass(Class<AGraphView> clazz) {
		synchronized (generalMutex) {
			if (clazz != null) {
				graphViewClazz = clazz;
				return true;
			}
		}
		return false;
	}
	
//=============================================================================
//-----------------Methods for creating graph view components------------------
	@Override
	public AGraphComparison newGraphComparison(Graph g1, Graph g2) {
		Class<?> tmpClazz;
		synchronized (generalMutex) {
			tmpClazz = graphComparisonViewClazz;
		}
		if (tmpClazz != null) {
			try {
				return (AGraphComparison)tmpClazz.getDeclaredConstructor(Graph.class, Graph.class).newInstance(g1, g2);
			} catch (Exception ex) {
				MainManager.log.printException(ex);
			}
		}
		return null;
	}
	
	@Override
	public AGraphView newGraphView(Graph g) {
		Class<?> tmpClazz;
		synchronized (generalMutex) {
			tmpClazz = graphViewClazz;
		}
		if (tmpClazz != null) {
			try {
				return (AGraphView)tmpClazz.getDeclaredConstructor(Graph.class).newInstance(g);
			} catch (Exception ex) {
				MainManager.log.printException(ex);
			}
		}
		return null;
	}
	
	@Override
	public AGraphView newGraphView(AGraphView graphView, Graph graph) {
		Class<?> tmpClazz;
		synchronized (generalMutex) {
			tmpClazz = graphViewClazz;
		}
		if (tmpClazz != null) {
			try {
				return (AGraphView)tmpClazz.getDeclaredConstructor(AGraphView.class, Graph.class).newInstance(graphView, graph);
			} catch (Exception ex) {
				MainManager.log.printException(ex);
			}
		}
		return null;
	}
}
